#include <bits/stdc++.h>
using namespace std;
int h[510][510]; // 高度矩阵

int f[510][510]; // 动态规划数组，用于存储结果

int dx[] = {0, 1, 0, -1}; // x方向的移动向量
int dy[] = {1, 0, -1, 0}; // y方向的移动向量
int n, m; // 矩阵的维度

// 计算从(x, y)开始的最长递减路径的函数
int dp(int x, int y) {
  if (f[x][y] != -1) // 如果已经计算过，返回存储的值
    return f[x][y];
  f[x][y] = 1; // 初始化路径长度为1（即当前单元格本身）
  for (int i = 0; i < 4; i++) { // 探索四个方向
    int a = x + dx[i], b = y + dy[i];
    // 检查新位置是否在边界内且高度较低
    if (a >= 1 && a <= n && b >= 1 && b <= m && h[a][b] < h[x][y]) {
      f[x][y] = max(f[x][y], dp(a, b) + 1); // 更新路径长度
    }
  }
  return f[x][y]; // 返回计算出的路径长度
}

int main() {
  cin >> n >> m; // 读取矩阵的维度
  memset(f, -1, sizeof f); // 初始化动态规划数组为-1
  for (int i = 1; i <= n; i++) // 读取高度矩阵
    for (int j = 1; j <= m; j++)
      cin >> h[i][j];

  int res = 0; // 存储最大路径长度的变量
  for (int i = 1; i <= n; i++) // 计算每个单元格的最长路径
    for (int j = 1; j <= m; j++)
      res = max(res, dp(i, j)); // 更新结果为找到的最大值

  cout << res << endl; // 输出结果

  return 0; // 程序结束
}